package com.videoweb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.videoweb.context.AuthenticationContextHolder;
import com.videoweb.entity.Favorites;
import com.videoweb.entity.User;
import com.videoweb.entity.UserRole;
import com.videoweb.entity.dto.UserInfoDTO;
import com.videoweb.mapper.UserMapper;
import com.videoweb.service.IFavoritesService;
import com.videoweb.service.IUserRoleService;
import com.videoweb.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lmr
 * @since 2025-05-17
 */
@Service
@Transactional

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

@Autowired
private UserMapper userMapper;
@Autowired
private IUserRoleService userRoleService;
@Autowired
private IFavoritesService favoritesService;


    @Override
    public List<User> findAllUsers() {
        return userMapper.selectList(null);
    }

    @Override
    public List<User> selectAllUser() {
        return userMapper.selectAllUser();
    }

    @Override
    public boolean addUser(User user) {
        boolean result = false;
//        添加角色
//         .setPassword(    passwordEncoder.encode("1234")
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        int row = userMapper.insert(user);
        if (row >0){
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
//            5 为普通用户
            userRole.setRoleId(5L);
            row = userRoleService.add(userRole);
        }
        if (row >0){
            Favorites favorites = new Favorites()
                    .setUserId(user.getId())
                    .setName("默认收藏夹")
                    .setDef(1);
            favoritesService.createFavorites(favorites);
            result = true;
        }
//         添加收藏夹（默认）
        return result;

    }

    @Override
    public User findUserByUserName(String username) {
        return userMapper.findUserByUserName(username);
    }

    @Override
    public UserInfoDTO getBaseUserInfo(Long userId) {

        User user = userMapper.selectById(userId);

        UserInfoDTO userInfoDTO = new UserInfoDTO();
//        第一种直接赋值
//       第二种使用SpringBoot的工具类(快但是容易出错，字段必须一致)
//        第三中使用 使用 MapStruct 自动映射（推荐，适合大型项目） 要下依赖

        //       第二种使用SpringBoot的工具类(快但是容易出错，字段必须一致)   后面的是目标，前面的是提供数据的
        BeanUtils.copyProperties(user,userInfoDTO);
//        todo: 得到用户的点赞量，关注，粉丝等信息
        userInfoDTO.setAllFans(456);
        userInfoDTO.setAllFollow(123);
        userInfoDTO.setAllLikes(789);


        return userInfoDTO;
    }


    @Override
    public void validate(User user) {
        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
        String username = usernamePasswordAuthenticationToken.getName();
        String password = usernamePasswordAuthenticationToken.getCredentials().toString();

        if (!matches(user, password))
        {
            // TODO: 2025/5/18    redis记录重试次数  + 抛出异常
//            密码错误的情况
//            retryCount = retryCount + 1;
//            redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);

            System.out.println("密码错误");

        }

        else
        {
            // TODO: 2025/5/18  保存到redis中
//            如果登录正确的话就保存登录记录到redis中
//            clearLoginRecordCache(username);
            System.out.println("保存登录记录到redis中");


        }

    }

//    对密码进行解码
    public boolean matches(User user, String rawPassword)
    {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(rawPassword, user.getPassword());
    }
}
